#!/usr/bin/python
# -*- coding: utf-8 -*-
# LD_PRELOAD=/usr/lib/libstdc++.so.6 python turp.py

__author__  = ('Kaan Akşit')

try:
    import pygame.camera,pygame,matplotlib,pygame.camera,time,sys,os,cmath,cv
    from scipy import *
    from numpy import *
    from numpy.fft import *
    from matplotlib.ticker import MaxNLocator
    from pygame.locals import *
    from scipy.signal import lfilter, iirdesign, butter, filtfilt
    matplotlib.use('GTKAgg')
    import math as mathe
    import matplotlib.pyplot as plt
    import gobject
    import argparse
except ImportError, err:
    print "couldn't load module. %s" % (err)
    sys.exit() 


# Şekil oluşturmak için ilgili sınıf
class sekil:
    def __init__(self,number,label,xdata,ydata,xlim,xtick,color,xmin=0,ymin=0,ylim=0):
        self.subplot = plt.subplot(number)
        self.canvas  = self.subplot.figure.canvas
        self.plt,    = plt.plot(ydata,xdata,color, animated=True)
        self.back    = self.canvas.copy_from_bbox(self.subplot.bbox)
        self.subplot.xaxis.set_major_locator(MaxNLocator(xtick))
        plt.yticks(arange(0))
        plt.ylabel(label)
        plt.xlim(xmin,xlim)
        if ylim!=0:
            plt.ylim(ymin,ylim)
        return
    def tazele(self,xdata,ydata):
        self.canvas.restore_region(self.back)
        self.plt.set_xdata(xdata)
        self.plt.set_ydata(ydata)
        self.subplot.relim()
        self.subplot.autoscale_view(scalex=True, scaley= True)
        self.subplot.draw_artist(self.plt)
        self.canvas.blit(self.subplot.bbox)
        return True

# Pencere oluşturmak için ilgili sınıf
class window:
    def __init__(self,width,height):
        localtime = time.asctime(time.localtime(time.time()))
        print "\x1b\x5b1;33;32m" + localtime + ', Kaan Akşit, 2011' + '\x1b[0m'
        print "\x1b\x5b1;31;40m" + 'Pygame version:'+ "\x1b[0m" + str(pygame.version.ver)
        pygame.init()
        window.screen     = pygame.display.set_mode((width, height),pygame.HWSURFACE)
        print "\x1b\x5b1;31;40m" + 'Video info:'+' '+ "\x1b[0m",
        print "\x1b\x5b1;33;20m", pygame.display.Info()
        self.background = pygame.Surface(window.screen.get_size())
        self.background.set_colorkey((250, 250, 250))
        pygame.display.set_icon(pygame.image.load(filepath("turp.png")))
        pygame.display.set_caption('turp')
    def text_blit(self,script,color,posx,posy,font_type,font_size):
        font            = pygame.font.Font(filepath(font_type),font_size)
        text            = font.render(unicode(script), 0, color)
        textpos         = text.get_rect()
        textpos.centerx = posx
        textpos.centery = posy
        self.background.blit(text,textpos)
        return textpos, script
    def rect_blit(self,rect,color=(255,0,0),width=0):
        pygame.draw.rect(self.background, color, rect, width)
        return True
    def tazele(self):
        window.screen.blit(self.background, (0, 0))
        pygame.display.flip()
        return True
    def blit(self,image,rect):
        self.background.fill((100, 100, 100))
        self.background.blit(image,rect)
        return True

# Web kamerası üzerinden görüntü alıp işlemek için ilgili sınıf
class cvkamera:
    def __init__(self,width,height):
        self.kaynak = cv.CreateCameraCapture(0)
        cv.SetCaptureProperty(self.kaynak,cv.CV_CAP_PROP_FRAME_WIDTH, width)
        cv.SetCaptureProperty(self.kaynak,cv.CV_CAP_PROP_FRAME_HEIGHT, height) 
        cv.SetCaptureProperty(self.kaynak,cv.CV_CAP_PROP_BRIGHTNESS,127)
        return
    def resimcik(self,kutu):
        cv.ResetImageROI(self.arabellek)
        cv.SetImageROI(self.arabellek,(kutu.left,kutu.right,kutu.width,kutu.height))
        kutucuk            = cv.CreateImage(cv.GetSize(self.arabellek), 8, 3)
        cv.Copy(self.arabellek,kutucuk)
        return kutucuk
    def yakala(self):
        self.arabellek = cv.QueryFrame(self.kaynak)
#        cv.Smooth(self.kaynak,self.kaynak,cv.CV_GAUSSIAN,1,0)
        cv.CvtColor(self.arabellek, self.arabellek, cv.CV_BGR2RGB)
        self.resim       = pygame.image.frombuffer(self.arabellek.tostring(),cv.GetSize(self.arabellek),'RGB')
        self.dikdortgen  = self.resim.get_rect()
        return self.resim,self.arabellek
    def gozbul(self):
        cv.matchTemplate(self.resim,self.ornekgoz,self.sonuc,CV_TM_CCOEFF_NORMED)
        return

# Hazır bir kaynaktan görüntü alıp işlemek için ilgili sınıf
class vidyo:
    def __init__(self,width,height,hedef):
        self.kaynak = cv.CaptureFromFile(hedef)
        return
    def resimcik(self,kutu):
        cv.ResetImageROI(self.arabellek)
        cv.SetImageROI(self.arabellek,(kutu.left,kutu.right,kutu.width,kutu.height))
        kutucuk            = cv.CreateImage(cv.GetSize(self.arabellek), 8, 3)
        cv.Copy(self.arabellek,kutucuk)
        return kutucuk
    def yakala(self):
        self.arabellek   = cv.QueryFrame(self.kaynak)
        if self.arabellek == None:
            sys.exit()
#        cv.Smooth(self.kaynak,self.kaynak,cv.CV_GAUSSIAN,1,0)
        cv.CvtColor(self.arabellek, self.arabellek, cv.CV_BGR2RGB)
        self.resim       = pygame.image.frombuffer(self.arabellek.tostring(),cv.GetSize(self.arabellek),'RGB')
        self.dikdortgen  = self.resim.get_rect()
        return self.resim,self.arabellek


def graph_init(function):
    gobject.idle_add(function)
    plt.show()
    return True
 
def filepath(filename):
    data_py  = os.path.abspath(os.path.dirname(__file__))
    if data_py == '/usr/bin':
        data_py = '/usr/share/turp'
    data_dir = os.path.normpath(os.path.join(data_py, 'veri'))
    return os.path.join(data_dir, filename)

def ayrikfourierdonusumu(veri,f):
    sp        = abs(fft(veri))
    Nr        = len(veri)
    freqstep  = float(f)/Nr
    freq      = freqstep * arange(0, Nr/2)
    freq      = freq[0:Nr/2]
    sp        = sp[0:Nr/2]
    return freq,sp

def routine():
    f             = tazeleme
    sayac         = 0
    kirp          = 40
    width         = 640; height= 480;
    wdw           = window(width,height)
    clock         = pygame.time.Clock()
    isaret        = zeros((pencereboyu,7))
    cillilikorani = zeros((1,4))
    kutu          = pygame.Rect(300,220,40,40)
    yarif         = float(f)/2
    [b,a]         = butter(2,[0.5/yarif,3./yarif],btype='bandpass') 
    if girdiler.hedef == None:
        kamera        = cvkamera(width,height)
    else:
        kamera        = vidyo(width,height,girdiler.hedef)
        print girdiler.hedef
    while True:
        events = pygame.event.get()
        kamera.yakala()
        for e in events:
            if e.type == QUIT or (e.type == KEYDOWN and e.key == K_ESCAPE):
                sys.exit()
                return
            if e.type == MOUSEBUTTONDOWN:
                [kutu.centerx, kutu.centery] = pygame.mouse.get_pos() 
#        kutu               = kamera.gozbul()
        # Resim içerisindeki ilgili alanın ortalamasını alıp, her ortalama renk değerini ilgili vektöre atar.
        kutucuk            = kamera.resimcik(kutu)
        [ortalama,sapma]   = cv.AvgSdv(cv.GetMat(kutucuk))
        isaret[sayac,0]    = ortalama[0]
        isaret[sayac,1]    = ortalama[1]
        isaret[sayac,2]    = ortalama[2]
        # Bütün ortalama renk değerlerini toplayıp tek bir vektöre yazar.
        isaret[:,3]        = isaret[:,0] + isaret[:,1] + isaret[:,2]
        # Yeşil ve mavi ortalama renk değerleri vektörünü 0.5 Hz ile 3 Hz arasında bant geçiş filteresine sokar.
        isaret[:,4]        = lfilter(b,a,isaret[:,0])
        isaret[:,5]        = lfilter(b,a,isaret[:,1])
        isaret[:,6]        = lfilter(b,a,isaret[:,2])
        # Filtrelenmiş değerlerin ayrık fourier dönüşümünü yapar.
        [fourier,frekans]  = ayrikfourierdonusumu(isaret[kirp:pencereboyu,5],15)
        # İlgili şekilleri günceller.
        sekil1.tazele(isaret[:,1],isaret[:,2])
        sekil2.tazele(xrange(0,pencereboyu),isaret[:,1])
        sekil3.tazele(xrange(kirp,pencereboyu),isaret[kirp:pencereboyu,5])
        sekil4.tazele(fourier[5:len(fourier)],frekans[5:len(frekans)])
        clock.tick(f)
        wdw.blit(kamera.resim,kamera.dikdortgen)
        wdw.rect_blit(kutu,(255,0,0),1)
        wdw.text_blit(('FPS: '+ str(int(clock.get_fps()))),[255,0,0],40,20,'yazi/ka1.ttf',12)
        wdw.tazele()
        if sayac == pencereboyu -1:
           sayac = 0
        else:
           sayac += 1
    return

def main():
    global sekil1,sekil2,sekil3,sekil4,pencereboyu,girdiler,tazeleme
    yorumlayici   = argparse.ArgumentParser(prog='turp', add_help=True,description='Uygulama hakkında bilgi buraya girilecek.')
    yorumlayici.add_argument('-k', '--kaynak', metavar='KONUM', type=argparse.FileType('rt'), help='Harici akışın konumunu belirler.', dest='hedef')
    yorumlayici.add_argument('-o', '--ornek', action='store_true', help='Örnek kaynağı indirip işler.', dest='ornek')
    yorumlayici.add_argument('--surum', action='version', version='%(prog)s 0.1')
    yorumlayici.add_argument('-t', '--tazeleme', action='store', help='Tazeleme oranını belirler.', dest='tazeleme', type=int)
    girdiler      = yorumlayici.parse_args()
    if girdiler.tazeleme == None:
        tazeleme      = 15
    else:
        tazeleme      = girdiler.tazeleme
    if girdiler.ornek == True:
        girdiler.hedef = './ornek.avi'
        if os.path.isfile('/usr/bin/youtube-dl') != True:
            if os.path.isfile("/etc/pardus-release") == True:
                print '\x1b\x5b1;33;32m','Pardus, youtube-dl yazılımını kurmak için sizden izin isteyecektir.','\x1b[0m'
                os.system('sudo pisi it youtube-dl')
                os.system('sudo youtube-dl -U')
            else:
                print '\x1b\x5b1;33;32m','Lütfen, youtube-dl yazılımını kurunuz.','\x1b[0m'
                sys.exit()
        if os.path.isfile('./ornek.avi') == False:
            print '\x1b\x5b1;33;32m','Örnek akış indiriliyor.','\x1b[0m'
            os.system('youtube-dl \"http://www.youtube.com/watch?v=El_vyOn_Zm4&hd=1\"')
            print '\x1b\x5b1;33;32m','Akış için gereken düzenlemeler yapılıyor.','\x1b[0m'
            os.system('ffmpeg -i El_vyOn_Zm4.mp4 -s 640x480 -r %s -b 2400000 ornek.avi' % tazeleme)
            os.system('rm -Rf El_vyOn_Zm4.mp4')
    # Göstereilecek olan şekiller için gerekli ayarlar yapılır.
    pencereboyu   = 255
    sekil1        = sekil(411,'Green vs Blue',xrange(0,pencereboyu),xrange(0,pencereboyu),pencereboyu,4,'b.',0,0,255)
    sekil2        = sekil(412,'Green',xrange(0,pencereboyu),xrange(0,pencereboyu),pencereboyu,4,'g')
    sekil3        = sekil(413,'Blue',xrange(0,pencereboyu),xrange(0,pencereboyu),pencereboyu,4,'b')
    sekil4        = sekil(414,'FFT',xrange(0,pencereboyu),xrange(0,pencereboyu),3,10,'r',0.75)
    graph_init(routine)
    return

if __name__ == "__main__":
  sys.exit(main())
